package com.moco.launcher.play;

/*import io.vov.vitamio.MediaPlayer;
 import io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener;
 import io.vov.vitamio.MediaPlayer.OnCompletionListener;
 import io.vov.vitamio.MediaPlayer.OnErrorListener;
 import io.vov.vitamio.MediaPlayer.OnInfoListener;
 import io.vov.vitamio.MediaPlayer.OnPreparedListener;
 import io.vov.vitamio.MediaPlayer.OnSeekCompleteListener;
 import io.vov.vitamio.MediaPlayer.OnTimedTextListener;*/

import java.io.File;

import android.app.Service;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.Environment;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.SeekBar;

import com.moco.launcher.LauncherApplication;
import com.moco.launcher.R;
import com.moco.launcher.adapter.DataAdapter;
import com.oazon.moco.bean.Metadata;
import com.oazon.moco.playlist.PlayListManage;

public class MediaController {

	private volatile static MediaController instance;
	private static final String TAG = "MediaController";
	private static Context mContext = null;
	// private int mCurrentIndex = 0;
	// final ArrayList<MusicItemInfo> mDefaultList = new
	// ArrayList<MusicItemInfo>();
	// ArrayList<MusicItemInfo> mPlayList = new ArrayList<MusicItemInfo>();
	private static boolean m_bDefaultList = true;
	private static long mPlayMode = -1;
	private LauncherApplication application = null;

	private View layout;

	/** Returns singleton class instance */
	public static MediaController getInstance() {
		if (instance == null) {
			synchronized (MediaController.class) {
				if (instance == null) {
					instance = new MediaController();
				}
			}
		}
		return instance;
	}

	public void init(Context context) {
		mContext = context;
		Service service = (Service) context;
		application = (LauncherApplication) service.getApplication();
		musicPlayerInit();

		LayoutInflater inflater = (LayoutInflater) mContext
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		layout = inflater.inflate(R.layout.playcontrol_layout, null);
	}

	private ListenCallback mListenCallback = new ListenCallback();

	private void musicPlayerInit() {
		AndroidMusicPlayer.getInstance().init(mContext);
		AndroidMusicPlayer.getInstance().setOnBufferingUpdateListener(
				mListenCallback);
		AndroidMusicPlayer.getInstance().setOnCompletionListener(
				mListenCallback);
		AndroidMusicPlayer.getInstance().setOnErrorListener(mListenCallback);
		AndroidMusicPlayer.getInstance().setOnInfoListener(mListenCallback);
		AndroidMusicPlayer.getInstance().setOnPreparedListener(mListenCallback);
		AndroidMusicPlayer.getInstance().setOnSeekCompleteListener(
				mListenCallback);
		// AndroidMusicPlayer.getInstance().setOnTimedTextListener(mListenCallback);
	}

	public long getDuration() {
		return AndroidMusicPlayer.getInstance().getDuration();
	}

	public long getCurrentPosition() {
		return AndroidMusicPlayer.getInstance().getCurrentPosition();
	}

	// public void setPlayList(List<MusicItemInfo> playList) {
	// // this.mPlayList = (ArrayList<MusicItemInfo>) playList;
	// }

	public String getCurrentUrl(boolean bDefault) {
		String ext = ".mp3";

		Metadata info = null;

		/*
		 * TODO Gavin if (bDefault &&
		 * (PlayListManage.getInstance().getReadIndex() >= 0)) { info =
		 * DataAdapter
		 * .dateAdapator(PlayListManage.getInstance().getCurrentMedia());
		 * 
		 * } else if (!bDefault && (PlayListManage.getInstance().getReadIndex()
		 * >= 0) && (PlayListManage.getInstance().size() > 0)) { if
		 * (PlayListManage.getInstance().getReadIndex() >=
		 * PlayListManage.getInstance().size())
		 * PlayListManage.getInstance().setReadIndex
		 * (PlayListManage.getInstance().size() - 1); info =
		 * DataAdapter.dateAdapator
		 * (PlayListManage.getInstance().getMedia(PlayListManage.getInstance()
		 * .getReadIndex())); }
		 */
		info = PlayListManage.getInstance().getCurrentMedia();
		if (info != null) {
			String savename = info.getItemID() + info.getTitle() + ext;
			String path = Environment.getExternalStorageDirectory()
					.getAbsolutePath();
			File f = new File(path + "/" + savename);
			if (f.exists()) {
				return f.getAbsolutePath();
			} else {
				return info.getRes().getValue();
			}
		}

		return "";
	}

	public void deleteCurrentItem() {
		Log.i("vincent", "is here ");
		if (m_bDefaultList) {
			if (PlayListManage.getInstance().getReadIndex() > 0)
				PlayListManage.getInstance().remove(
						PlayListManage.getInstance().getReadIndex());
		} else {
			if (PlayListManage.getInstance().getReadIndex() > 0
					&& PlayListManage.getInstance().getReadIndex() < PlayListManage
							.getInstance().size())
				PlayListManage.getInstance().remove(
						PlayListManage.getInstance().getReadIndex());
		}
	}

	public String getCurrentId(boolean bDefault) {

		if (PlayListManage.getInstance().getCurrentMedia() != null && bDefault
				&& (PlayListManage.getInstance().getReadIndex() >= 0)) {

			return PlayListManage.getInstance().getCurrentMedia().getId();

		} else if (!bDefault
				&& (PlayListManage.getInstance().getReadIndex() >= 0)
				&& (PlayListManage.getInstance().size() > 0)
				&& PlayListManage.getInstance().getMedia(
						PlayListManage.getInstance().getReadIndex()) != null) {

			return PlayListManage.getInstance()
					.getMedia(PlayListManage.getInstance().getReadIndex())
					.getItemID();
		}
		return "";
	}

	public long getAudioSessionId() {
		return AndroidMusicPlayer.getInstance().getAudioTrack();
	}

	public void setPlayMode(long mode) {
		mPlayMode = mode;
	}

	public void playItem(MusicItemInfo info) {
		if (info != null) {
			if (AndroidMusicPlayer.getInstance().isPlaying()) {
				AndroidMusicPlayer.getInstance().stop();
				// onPause();
			}
			/*
			 * TODO gavin if
			 * (PlayListManage.getInstance().getIndex(info.getId()) != -1) {
			 * PlayListManage
			 * .getInstance().setReadIndex(PlayListManage.getInstance
			 * ().getIndex(info.getId())); }
			 */
			AndroidMusicPlayer.getInstance().setVideoPath(info.getUrl());
		}
	}

	public void setVolume(float leftVolume, float rightVolume) {
		AndroidMusicPlayer.getInstance().setVolume(leftVolume, rightVolume);
	}

	public void registerStatusChangeCallback(OnStatusChangeCallback callback) {
		if (mCallbacks != null && callback != null) {
			mCallbacks.register(callback);
		}
	}

	public void unregisterStatusChangeCallback(OnStatusChangeCallback callback) {
		if (mCallbacks != null && callback != null) {
			mCallbacks.unregister(callback);
		}
	}

	RemoteCallbackList<OnStatusChangeCallback> mCallbacks = new RemoteCallbackList<OnStatusChangeCallback>();

	public void onSeek() {
		final int N = mCallbacks.beginBroadcast();
		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				mCallbacks.getBroadcastItem(i).onSeekComplete(
						PlayListManage
								.getInstance()
								.getMedia(
										PlayListManage.getInstance()
												.getReadIndex()).getItemID());
			} catch (Exception e) {
				// The RemoteCallbackList will take care of removing
				// the dead object for us.
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void onPlay() {
		Log.d(TAG, "onPlay");
		int N = -1;
		try {
			N = mCallbacks.beginBroadcast();
		} catch (Exception e) {
			return;
		}

		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				mCallbacks.getBroadcastItem(i).onPlaying();
			} catch (RemoteException e) {
				e.printStackTrace();

			}
		}
		mCallbacks.finishBroadcast();
	}

	public void onPause() {
		final int N = mCallbacks.beginBroadcast();
		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				if (PlayListManage.getInstance().getMedia(
						PlayListManage.getInstance().getReadIndex()) != null) {
					mCallbacks.getBroadcastItem(i).onPause(
							PlayListManage
									.getInstance()
									.getMedia(
											PlayListManage.getInstance()
													.getReadIndex())
									.getItemID());
				}
			} catch (RemoteException e) {
				// The RemoteCallbackList will take care of removing
				// the dead object for us.
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void onStop() {
		final int N = mCallbacks.beginBroadcast();
		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				if (PlayListManage.getInstance().getMedia(
						PlayListManage.getInstance().getReadIndex()) != null) {
					mCallbacks.getBroadcastItem(i).onStop(
							PlayListManage
									.getInstance()
									.getMedia(
											PlayListManage.getInstance()
													.getReadIndex())
									.getItemID());
				}
			} catch (Exception e) {
				// The RemoteCallbackList will take care of removing
				// the dead object for us.
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void onError(int nError) {
		final int N = mCallbacks.beginBroadcast();
		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				mCallbacks.getBroadcastItem(i).onError(nError);
			} catch (RemoteException e) {
				// The RemoteCallbackList will take care of removing
				// the dead object for us.
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void startPlayList(boolean bDefault) {
		// TODO ??
		/*
		 * if (AndroidMusicPlayer.getInstance().isPlaying()) {
		 * AndroidMusicPlayer.getInstance().stop(); }
		 * 
		 * m_bDefaultList = bDefault;
		 * PlayListManage.getInstance().setReadIndex(0); String url =
		 * this.getCurrentUrl(bDefault); Log.d(TAG, "url = " + url); if
		 * (!url.isEmpty()) AndroidMusicPlayer.getInstance().setVideoPath(url);
		 */
	}

	public void playCurrent() {
		// TODO ???
		String url = getCurrentUrl(m_bDefaultList);
		if (url.isEmpty()) {
			//AndroidMusicPlayer.getInstance().stop();
			return;
		}
		AndroidMusicPlayer.getInstance().setVideoPath(url);
	}

	public void playNext() {
		Log.d(TAG, "playNext");
		int N = -1;
		try {
			N = mCallbacks.beginBroadcast();
		} catch (Exception e) {
			return;
		}

		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				mCallbacks.getBroadcastItem(i).playNext();;
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void playPrev() {
		Log.d(TAG, "playPrev");
		int N = -1;
		try {
			N = mCallbacks.beginBroadcast();
		} catch (Exception e) {
			return;
		}

		Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);
		for (int i = 0; i < N; i++) {
			Log.i(TAG, "I = " + String.valueOf(i));
			try {
				mCallbacks.getBroadcastItem(i).playPre();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		mCallbacks.finishBroadcast();
	}

	public void start() {
		AndroidMusicPlayer.getInstance().start();
	}

	public void stop() {
		AndroidMusicPlayer.getInstance().stop();
		// onStop();
	}

	public void pause() {
		AndroidMusicPlayer.getInstance().pause();
		// onPause();
	}

	public void seekTo(long msec) {
		AndroidMusicPlayer.getInstance().seekTo(msec);
	}

	public boolean isPlaying() {
		return AndroidMusicPlayer.getInstance().isPlaying();
	}

	private class ListenCallback implements OnInfoListener,
			OnBufferingUpdateListener, OnPreparedListener,
			OnCompletionListener, OnErrorListener, OnSeekCompleteListener {

		@Override
		public void onCompletion(MediaPlayer mp) {
			// TODO Auto-generated method stub
			Log.d(TAG, "onCompletion........." + getCurrentId(false));
			onStop();
			if (mPlayMode == 0) {
				playCurrent();
			} else {
				playNext();
			}
		}

		@Override
		public void onPrepared(MediaPlayer mp) {
			// TODO Auto-generated method stub
			Log.d(TAG, "onPrepared......");
			onPlay();
			mp.start();
		}

		@Override
		public void onBufferingUpdate(MediaPlayer mp, int percent) {
			// TODO Auto-generated method stub
			// LayoutInflater inflater = (LayoutInflater) mContext
			// .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			// View layout = inflater.inflate(R.layout.playcontrol_layout,
			// null);
			SeekBar mProgress = (SeekBar) layout
					.findViewById(R.id.mediacontroller_seekbar);
			mProgress.setSecondaryProgress(percent);
		}

		@Override
		public boolean onInfo(MediaPlayer mp, int what, int extra) {
			// TODO Auto-generated method stub
			switch (what) {
			case MediaPlayer.MEDIA_INFO_BUFFERING_START:
				Log.d(TAG, "MEDIA_INFO_BUFFERING_START");
				break;
			case MediaPlayer.MEDIA_INFO_BUFFERING_END:
				Log.d(TAG, "MEDIA_INFO_BUFFERING_END");
				// TODO gavin onPlay();
				AndroidMusicPlayer.getInstance().start();
				break;
			/*
			 * case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED: break;
			 */
			}
			return true;
		}

		@Override
		public boolean onError(MediaPlayer mp, int what, int extra) {
			MediaController.this.onError(what);
			return false;
		}

		@Override
		public void onSeekComplete(MediaPlayer mp) {
			// TODO Auto-generated method stub
			onSeek();
		}

	};

	public interface MediaPlayerControl {
		void start();

		void pause();

		long getDuration();

		long getCurrentPosition();

		void seekTo(long pos);

		boolean isPlaying();

		int getBufferPercentage();
	}
}